package org.linkminder.servlet;

import java.io.*;

import java.util.logging.Logger;
import java.util.*;

import org.linkminder.LinkMinder;
import org.linkminder.LinkMinderException;

import com.google.wave.api.*;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;

/**
 * 
 * @author jackpark
 * @author mark.carranza
 *
 */


@SuppressWarnings("serial")
public class LinkMinderServlet extends AbstractRobotServlet {
	
	 /**
	   * The key of a wave id.
	   */
	  private static final String WAVE_ID = "waveID";
	  
	  /**
	   * The key of a wavelet id.
	   */
	  private static final String WAVELET_ID = "waveletID";
	  
	  /**
	   * The key of a blip id.
	   */
	  private static final String BLIP_ID = "blipID";
	  
	private static final Logger log =
	      Logger.getLogger(LinkMinderServlet.class.getName());
	private LinkMinder brains;
	
	public void init()
    	throws ServletException {
		super.init();
		log.info("LinkMinderServlet.init- ");
		try {
			ServletConfig config = super.getServletConfig();
			ServletContext m_context = config.getServletContext();
	        File  	m_homeDir = new File(m_context.getRealPath("/")); 
	        File webInfDir = new File(m_homeDir, "WEB-INF");
	        //path for RDBMS database
	        File data = new File(webInfDir, "data");
			brains = new LinkMinder(data.getAbsolutePath());
		} catch (Exception e) {
			log.info("LinkMinderServlet.init error "+e.getMessage());
			throw new ServletException(e);
		}
	
	}
    public void destroy() {
     	brains.shutDown();
    }

	/* (non-Javadoc)
	 * @see com.google.wave.api.AbstractRobotServlet#processEvents(com.google.wave.api.RobotMessageBundle)
	 */
	@Override
	public void processEvents(RobotMessageBundle bundle) {
	    Wavelet wavelet = bundle.getWavelet();
	    
	    // start to gather ids for new wavelet (not finished)	    
	    String waveID = wavelet.getDataDocument(WAVE_ID);
	    
	    Blip rootBlip = wavelet.getRootBlip();
	    FormElement inputText = 
    		new FormElement(ElementType.INPUT, "entry");
		log.info("LinkMinderServlet.processEvents- ");

		// more than one wavelet in a wave
	    if (bundle.wasSelfAdded()) {
			log.info("LinkMinderServlet.processEvents- wasSelfAdded");
	        TextView textView = rootBlip.getDocument();
	        textView.append("What are you thinking?");
	        FormView formView = textView.getFormView();	    	
	    	formView.append(inputText);
	    	FormElement rootSubmitButton = 
	    		new FormElement(ElementType.BUTTON, "title", "enter");
	    	// this was NOT visible when appended to formView
	    	textView.appendElement(rootSubmitButton);
	    	// "done" the rootBlip
       }
	    Blip eventBlip = null;
	    Blip childBlip = null;
	    TextView textView = null;
	    FormView formView = null;
	    FormElement inputElement = null;
	    String entry = "";
	    String buttonClicked = "";
	   // Handle various events.
	    for (Event e : bundle.getEvents()) {
	      switch (e.getType()) {
	        case FORM_BUTTON_CLICKED:
	        	//form button could be the enter button in the root wavelet where the user
	        	//has entered some idea as a search
	        	//form button could also be a select button inside a child blip meaning
	        	//the search idea has just changed: we are pivoting on that selected idea
	    		log.info("LinkMinderServlet.processEvents formButtonClicked: " + e.getButtonName());
	    		
	    		entry = getBlipEntry(e.getBlip());
	    		
	    		log.info("LinkMinderServlet.processEvents formButtonClicked inputElement: " + entry);
	    		// todo: test text not empty or duplicate
	    			    		
	    		if (e.getButtonName().equals("title")) {
	    			// create a child wavelet under root blip
	    			log.info("LinkMinderServlet.processEvents formButtonClicked: createChild wavelet");
	    			
	    			List<String>ideas = null;
	    			try {
	    				ideas = brains.getLocalIdea(entry);
	    			} catch (LinkMinderException x) {
	    				//todo
	    				log.info("LinkMinderServlet.processEvents forButtonClicked error "+ideas);
	    			}
    				log.info("LinkMinderServlet.processEvents forButtonClicked got ideas "+ideas);
	    			if (ideas != null)
	    				populateList(rootBlip,entry,ideas);
	    			
	    			/*childBlip = listWavelet.appendBlip();
	    	        textView = childBlip.getDocument();
	    	        formView = textView.getFormView();	    	
	    	    	FormElement submitButton = 
	    	    		new FormElement(ElementType.BUTTON, "entry", "enter");
	    	    	formView.append(inputText);
	    	    	formView.append(submitButton); */
	    		}	    		
	          // theoretically speaking, this could be a button to "clear the screen" in the root blip
	          //TODO generalize this to New Question, New Answer, New Pro, New Con
	         
	          break;
	        case BLIP_SUBMITTED:
	    		log.info("LinkMinderServlet.processEvents blipSubmitted ");
	        	String query = "nothing";
	        	eventBlip = e.getBlip();
	        	textView = eventBlip.getDocument();
	        	entry = textView.getText();
			    childBlip = eventBlip.getParent();
		        textView = childBlip.getDocument();
		        query = textView.getText();
		        log.info("LinkMinderServlet.processEvents blipSubmitted 1 "+entry+" "+query);
		        try {
		        	this.brains.associateLocalIdeas(query, entry);
		        } catch (LinkMinderException x) {
		        	log.info("LinkMinderServlet blip_submitted error "+x.getMessage());
		        }
	        	
	    		log.info("LinkMinderServlet.processEvents blipSubmitted 2 "+entry+" "+query);
	          // this is where we will handle a new idea using LinkMinder
	          break;
	        case DOCUMENT_CHANGED:
	    		entry = getBlipEntry(e.getBlip());
	    		log.info("LinkMinderServlet.processEvents documentChanged "+entry);
	          // probably don't need this one
	          break;
	      }
	    }
	}
	
	private String getBlipEntry(Blip blip) {
		// get text in "entry" field		
		return blip.getDocument().getFormView().getFormElement("entry").getValue();
	}
	
	private void populateList(Blip parent, String query, List<String>ideas) {
		boolean hasChildren = parent.hasChildren();
		log.info("LinkMinderServlet.populateList"+ideas+" "+hasChildren+" "+query);
		Blip kid = null;
		int len;
		if (hasChildren) {
			List<Blip> kids = parent.getChildren();
			len = kids.size();
			for (int i=0;i<len;i++) {
				kid = kids.get(i);
				kid.delete();//nuke the snappers
			}
		}
		len = ideas.size();
	    TextView textView = null;
		Blip child = parent.createChild();
		textView = child.getDocument();
		textView.append(query);
		//new entry blip
		kid = child.createChild();
		textView = kid.getDocument();
		textView.append("Edit Me: New Idea");

		for (int i=0;i<len;i++) {
			kid = child.createChild();
			textView = kid.getDocument();
			textView.append(ideas.get(i));
		}
	}
}
